﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.ComponentModel;
using SDF.Primitives;

namespace SDF
{
    public abstract class SmartInline : SmartDataObject
    {
        #region Constructors

        protected SmartInline()
        {
        }

        #endregion

        #region Dependency Properties

        public static readonly DependencyProperty ForegroundProperty = Inline.ForegroundProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty FontFamilyProperty = Inline.FontFamilyProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty FontSizeProperty = Inline.FontSizeProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty FontStretchProperty = Inline.FontStretchProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty FontStyleProperty = Inline.FontStyleProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty FontWeightProperty = Inline.FontWeightProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty TextEffectsProperty = Inline.TextEffectsProperty.AddOwner(typeof(SmartInline));


        public static readonly DependencyProperty BackgroundProperty = Inline.BackgroundProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty BaselineAligmentProperty = Inline.BaselineAlignmentProperty.AddOwner(typeof(SmartInline));
        public static readonly DependencyProperty TextDecorationsProperty = Inline.TextDecorationsProperty.AddOwner(typeof(SmartInline));

        #endregion

        #region Properties

        public Brush Background
        {
            get { return (Brush)GetValue(BackgroundProperty); }
            set { SetValue(BackgroundProperty, value); }
        }

        public BaselineAlignment BaselineAlignment
        {
            get { return (BaselineAlignment)GetValue(BaselineAligmentProperty); }
            set { SetValue(BaselineAligmentProperty, value); }
        }

        public Brush Foreground
        {
            get { return (Brush)GetValue(ForegroundProperty); }
            set { SetValue(ForegroundProperty, value); }
        }

        public FontFamily FontFamily
        {
            get { return (FontFamily)GetValue(FontFamilyProperty); }
            set { SetValue(FontFamilyProperty, value); }
        }

        public double FontSize
        {
            get { return (double)GetValue(FontSizeProperty); }
            set { SetValue(FontSizeProperty, value); }
        }

        public FontStretch FontStretch
        {
            get { return (FontStretch)GetValue(FontStretchProperty); }
            set { SetValue(FontStretchProperty, value); }
        }

        public FontStyle FontStyle
        {
            get { return (FontStyle)GetValue(FontStyleProperty); }
            set { SetValue(FontStyleProperty, value); }
        }

        public FontWeight FontWeight
        {
            get { return (FontWeight)GetValue(FontWeightProperty); }
            set { SetValue(FontWeightProperty, value); }
        }

        public double LineHeight
        {
            get { return FontFamily.LineSpacing * FontSize; }
        }

        public TextDecorationCollection TextDecorations
        {
            get { return (TextDecorationCollection)GetValue(TextDecorationsProperty); }
            set { SetValue(TextDecorationsProperty, value); }
        }

        public TextEffectCollection TextEffects
        {
            get { return (TextEffectCollection)GetValue(TextEffectsProperty); }
            set { SetValue(TextEffectsProperty, value); }
        }

        #endregion

        #region Parent/Child Implementation

        public IInlineContainer Parent
        {
            get { return SmartLogicalTreeHelper.GetParent(this) as IInlineContainer; }
        }

        public virtual bool IsValidParent(DependencyObject parent)
        {
            return (parent is IInlineContainer);
        }

        #endregion

        #region GetParagraphSize Method

        // A SmartInline is ALWAYS contained in a Paragraph, directly or indirectly. This method returns the 
        // space currently available to the paragraph in the measure pass.
        public Size GetParagraphSize()
        {
            var paragraph = this.Parent as Paragraph;
            if (paragraph != null)
                return paragraph.GetCurrentAvailableSize();

            var inline = this.Parent as SmartInline;
            if (inline != null)
                return inline.GetParagraphSize();

            return new Size();
        }

        #endregion

        #region IsVisualProperty

        protected override bool IsVisualProperty(string propertyName)
        {
            switch (propertyName)
            { 
                case "Foreground":
                case "FontFamily":
                case "FontSize":
                case "FontStretch":
                case "FontStyle":
                case "FontWeigth":
                case "TextEffects":
                case "Background":
                case "BaselineAlignment":
                case "TextDecorations":
                    return true;

                default:
                    return base.IsVisualProperty(propertyName);
            }
        }

        #endregion

        #region CopyProperties

        protected virtual void CopyProperties(SmartInline copy)
        {
            copy.Background = this.Background;
            copy.FontFamily = this.FontFamily;
            copy.FontSize = this.FontSize;
            copy.FontStretch = this.FontStretch;
            copy.FontStyle = this.FontStyle;
            copy.FontWeight = this.FontWeight;
            copy.Foreground = this.Foreground;
            copy.TextEffects = this.TextEffects;
        }

        #endregion

    }
}
